package zmmMember

import (
	"context"
	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gtime"
	"github.com/tiger1103/gfast/v3/api/v1/zmm"
	"github.com/tiger1103/gfast/v3/internal/app/zmm/dao"
	"github.com/tiger1103/gfast/v3/internal/app/zmm/model/do"
	"github.com/tiger1103/gfast/v3/internal/app/zmm/model/entity"
	"github.com/tiger1103/gfast/v3/internal/app/zmm/service"

	"github.com/tiger1103/gfast/v3/library/liberr"
)

func init() {
	service.RegisterZmmMember(New())
}

func New() *sZmmMember {
	return &sZmmMember{}
}

type sZmmMember struct {
}

func (s *sZmmMember) GetList(ctx context.Context, req *zmm.ZmmMemberListReq) (total interface{}, list []*entity.ZmmMember, err error) {
	where := g.Map{}
	if req.Name != "" {
		where["name like ?"] = "%" + req.Name + "%"
	}
	if req.Status != "" {
		where["status"] = req.Status
	}
	if req.Contact != "" {
		where["contact"] = req.Contact
	}
	m := dao.ZmmMember.Ctx(ctx)
	total, err = m.Where(where).Count()

	err = m.Where(where).Page(req.PageNum, req.PageSize).OrderDesc("id").FieldsEx("deleted_at").Scan(&list)
	if err != nil {
		return
	}

	if len(list) > 0 {
		for _, member := range list {
			member.JoinEmployee = gdb.Record{}
			if member.JoinEmployeeId > 0 {
				member.JoinEmployee, _ = dao.ZmmEmployee.Ctx(ctx).Fields("id,name").Where("id", member.JoinEmployeeId).One()
			}
		}
	}

	return
}

func (s *sZmmMember) GetOpQuery(ctx context.Context, req *zmm.ZmmMemberOpQueryListReq) (list []*entity.ZmmMember, err error) {
	if req.OpQuery == "" {
		return nil, gerror.New("查询参数错误")
	}
	m := dao.ZmmMember.Ctx(ctx)
	err = m.Where("status = 1 and  (name like ? or contact like ?)", "%"+req.OpQuery+"%", "%"+req.OpQuery+"%").Fields("id,name,contact,money").Scan(&list)
	return
}

func (s *sZmmMember) Edit(ctx context.Context, req *zmm.ZmmMemberEditReq) (id uint64, err error) {
	err = g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		err = g.Try(ctx, func(ctx context.Context) {
			if req.ID > 0 {
				_, err = dao.ZmmMember.Ctx(ctx).TX(tx).Where("id", req.ID).Update(do.ZmmMember{
					Name:           req.Name,
					Contact:        req.Contact,
					Status:         req.Status,
					Remark:         req.Remark,
					JoinEmployeeId: req.JoinEmployeeId,
				})
			} else {
				insertId, e := dao.ZmmMember.Ctx(ctx).TX(tx).InsertAndGetId(do.ZmmMember{
					Name:           req.Name,
					Contact:        req.Contact,
					Status:         req.Status,
					Remark:         req.Remark,
					JoinTime:       gtime.Now(),
					Money:          0,
					JoinEmployeeId: req.JoinEmployeeId,
				})
				req.ID = uint64(insertId)
				err = e
			}

			liberr.ErrIsNil(ctx, err)
		})
		return err
	})
	return req.ID, err
}

func (s *sZmmMember) Delete(ctx context.Context, req *zmm.ZmmMemberDelReq) error {
	_, err := dao.ZmmMember.Ctx(ctx).Where(dao.ZmmMember.Columns().Id, req.ID).Delete()
	liberr.ErrIsNil(ctx, err, "删除失败")
	return err
}

func (s *sZmmMember) Recharge(ctx context.Context, req *zmm.ZmmMemberRechargeReq) (err error) {
	if req.ID == 0 {
		return gerror.New("参数错误")
	}
	if req.RechargeMoney == 0 {
		return gerror.New("请确认充值金额")
	}

	err = g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		err = g.Try(ctx, func(ctx context.Context) {
			member := entity.ZmmMember{}
			err = dao.ZmmMember.Ctx(ctx).Where("id", req.ID).Scan(&member)
			if err != nil {
				return
			}

			member.Money += req.RechargeMoney
			_, err := dao.ZmmMember.Ctx(ctx).Save(member)
			liberr.ErrIsNil(ctx, err)

			// 记录日志
			err = service.ZmmMoneyLogMember().SaveMemberLog(ctx, &do.ZmmMoneyLogMember{
				MemberId: req.ID,
				Money:    req.RechargeMoney,
				TypeData: 1,
				Remark:   req.Remark,
			})
			liberr.ErrIsNil(ctx, err)
			// 查找上级baseshopid
			baseShopId, _ := dao.ZmmShop.Ctx(ctx).TX(tx).Where("id", req.ShopId).Value("up_id")

			err = service.ZmmMoneyLogShop().SaveShopLog(ctx, &do.ZmmMoneyLogShop{
				MemberId:   req.ID,
				Money:      req.RechargeMoney,
				TypeData:   1,
				Remark:     req.Remark,
				BaseShopId: baseShopId,
				ShopId:     req.ShopId,
			})
			liberr.ErrIsNil(ctx, err)
		})
		return err
	})

	return
}

func (s *sZmmMember) Consumption(ctx context.Context, req *service.ZmmMemberConsumption) (err error) {
	if req.ID == 0 {
		return gerror.New("参数错误")
	}
	if req.Money <= 0 {
		return gerror.New("请确认消费金额")
	}

	err = g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		err = g.Try(ctx, func(ctx context.Context) {
			member := entity.ZmmMember{}
			err = dao.ZmmMember.Ctx(ctx).Where("id", req.ID).Scan(&member)
			if err != nil {
				liberr.ErrIsNil(ctx, err)
			}

			if req.Money > member.Money {
				liberr.ErrIsNil(ctx, gerror.New("会员余额不足"))
			}

			member.Money -= req.Money
			_, err := dao.ZmmMember.Ctx(ctx).Save(member)
			liberr.ErrIsNil(ctx, err)

			// 记录日志
			err = service.ZmmMoneyLogMember().SaveMemberLog(ctx, &do.ZmmMoneyLogMember{
				MemberId: req.ID,
				Money:    req.Money,
				OrderId:  req.OrderID,
				TypeData: 2,
				Remark:   req.Remark,
			})
			liberr.ErrIsNil(ctx, err)

		})
		return err
	})
	return
}
